{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "44a71f52",
   "metadata": {},
   "source": [
    "# 习题\n",
    "## 习题16.1\n",
    "![image.png](./images/exercise1.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "88ad4caa",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "正交矩阵V：\n",
      "[[ 0.707  0.707]\n",
      " [ 0.707 -0.707]]\n",
      "样本主成分矩阵Y：\n",
      "[[-2.028 -0.82  -0.433  0.     0.82   2.461]\n",
      " [ 0.296 -0.046 -0.433  0.     0.046  0.137]]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "\n",
    "def pca_svd(X, k):\n",
    "    \"\"\"\n",
    "    样本矩阵的奇异值分解的主成分分析算法\n",
    "    :param X: 样本矩阵X\n",
    "    :param k: 主成分个数k\n",
    "    :return: 特征向量V，样本主成分矩阵Y\n",
    "    \"\"\"\n",
    "    n_samples = X.shape[1]\n",
    "\n",
    "    # 构造新的n×m矩阵\n",
    "    T = X.T / np.sqrt(n_samples - 1)\n",
    "\n",
    "    # 对矩阵T进行截断奇异值分解\n",
    "    U, S, V = np.linalg.svd(T)\n",
    "    V = V[:, :k]\n",
    "\n",
    "    # 求k×n的样本主成分矩阵\n",
    "    return V, np.dot(V.T, X)\n",
    "\n",
    "X = np.array([[2, 3, 3, 4, 5, 7],\n",
    "              [2, 4, 5, 5, 6, 8]])\n",
    "X = X.astype(\"float64\")\n",
    "\n",
    "# 规范化变量\n",
    "avg = np.average(X, axis=1)\n",
    "var = np.var(X, axis=1)\n",
    "for i in range(X.shape[0]):\n",
    "    X[i] = (X[i, :] - avg[i]) / np.sqrt(var[i])\n",
    "\n",
    "# 设置精度为3\n",
    "np.set_printoptions(precision=3, suppress=True)\n",
    "V, vnk = pca_svd(X, 2)\n",
    "\n",
    "print(\"正交矩阵V：\")\n",
    "print(V)\n",
    "print(\"样本主成分矩阵Y：\")\n",
    "print(vnk)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b5343865",
   "metadata": {},
   "source": [
    "# 使用Coursera机器学习课程的第六个编程练习"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "d81ad96d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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xgAAACRNMAYAACBpgjEAAABJE4wBAABImmAMAABA0gRjAAAAkiYYAwAAkDTBGAAAgKQJxgAAACRNMAYAACBpgjEAAABJE4wBAABImmAMAABA0gRjAAAAkiYYAwAAkLSGg/FPf/rTOHfuXNx0001x9913x89//vNW1AUAAABt0XAwfs973hP33ntvPPHEE/G6170uPvCBD7SiLgAAAGiLhoLx888/HzfddFN89KMfjdtuuy3e9a53xfLycqtqAwAAgJY70cjFt9xyS/zgBz+IiIgXX3wxvv71r8eb3vSmPa+9evVqXL16dfvx+vr6EcoEAACA1mgoGF/rxhtvjFOnTsVjjz225/fvv//+mJmZOXRhAAAA0A65Wq1WO8z/cHFxMT7+8Y9Hb29vPPLII7u+v9eJ8ZkzZ6JcLsfAwMDhKwYAAIADWF9fj3w+f90c2lAw/s1vfhNPP/30dvv0448/HmNjY/HCCy9EPp9vSkEAAADQDAfNoQ0N33r88cfjHe94x/bjXC639Q/psQ4ZAACA7tRQoh0fH49KpRIPPvhgPP300/G5z30u7r777ujv729VfQAAANBSDQXjm2++Ob75zW/Gl7/85bjzzjvj2Wefja9+9autqg0AAABaruGp1G9961vjxz/+cStqAQAAgLZzczAAAABJE4wBAABImmAMAABA0hq+x/g426zWYmFlLVY3KjHU3xfjI4PR25PLuiwAAABaSDD+b/NLpZiZW45SubL93HC+L6YnizExOpxhZQAAALSSVurYCsVTs4s7QnFExJVyJaZmF2N+qZRRZQAAALRa8sF4s1qLmbnlqO3xvfpzM3PLsVnd6woAAAC6XfLBeGFlbddJ8bVqEVEqV2JhZa19RQEAANA2yQfj1Y39Q/FhrgMAAKC7JB+Mh/r7mnodAAAA3SX5YDw+MhjD+b7YbylTLramU4+PDLazLAAAANok+WDc25OL6cliRMSucFx/PD1ZtM8YAADgmEo+GEdETIwOx8ULY1HI72yXLuT74uKFMXuMAQAAjrETWRfQKSZGh+N8sRALK2uxulGJof6t9mknxQAAAMebYHyN3p5cnDt7KusyAAAAaCOt1AAAACRNMAYAACBpgjEAAABJE4wBAABImmAMAABA0gRjAAAAkiYYAwAAkDTBGAAAgKQJxgAAACRNMAYAACBpgjEAAABJE4wBAABImmAMAABA0gRjAAAAkiYYAwAAkDTBGAAAgKQJxgAAACRNMAYAACBpgjEAAABJE4wBAABI2ol2vVCtVouIiPX19Xa9JAAAAAmr5896Ht1P24LxxsZGREScOXOmXS8JAAAAsbGxEfl8ft/v52rXi85NUq1W45lnnon+/v7I5XL7Xre+vh5nzpyJp556KgYGBtpRGjSdn2OOCz/LHBd+ljku/CxzHLTz57hWq8XGxkbcdttt0dOz/53EbTsx7unpide85jUHvn5gYMBfdrqen2OOCz/LHBd+ljku/CxzHLTr5/iVTorrDN8CAAAgaYIxAAAASeu4YHzy5MmYnp6OkydPZl0KHJqfY44LP8scF36WOS78LHMcdOLPcduGbwEAAEAn6rgTYwAAAGgnwRgAAICkCcYAAAAkTTAGAAAgaR0XjEulUtxzzz1x6dKlrEuBQ3vyySfjnnvuif7+/njrW98a//7v/551SdCwn/70p3Hu3Lm46aab4u67746f//znWZcER/Loo49GLpeL733ve1mXAody1113RS6X2/46ffp01iXBobz00ktx3333RX9/fxSLxVhYWMi6pM4Kxvfdd1/cdttt8eijj2ZdChzJX/zFX8Qf/MEfxNLSUpw6dSr+8i//MuuSoGHvec974t57740nnngiXve618UHPvCBrEuCQ3vppZfigx/8YNZlwJG88MIL8Z3vfCeef/75eP755+PJJ5/MuiQ4lM9+9rPxy1/+Mh5//PF497vfHRcuXMi6pDiRdQHX+tu//dv42Mc+FiMjI1mXAof24osvxne/+91YWlqKP/zDP4z3ve998ad/+qdZlwUNef755+Omm26Kj370o/HqV7863vWud8X73ve+rMuCQ/v85z8fQ0ND8fTTT2ddChxauVyOkZGRuPnmm7MuBY7kK1/5SnzjG9+IO+64Iz7ykY9EsViMarUaPT3Zndt21Inx6dOn47WvfW3WZcCRvPTSS/GZz3xm+wOe5557Lm644YaMq4LG3HLLLfGDH/wgXv3qV8eLL74YX//61+NNb3pT1mXBoTz99NPx6U9/Oh588MGsS4EjeeGFF+ITn/hE3HDDDfHGN74xfvKTn2RdEjTsypUr8eSTT8b3v//9yOfzcc8998Qb3vCGTENxRIcFYzgOfu/3fi/++q//Om644YZ46aWX4u///u/jz//8z7MuCw7txhtvjG9/+9vxxS9+MetS4FA+/OEPx3333Rd33nln1qXAob344otRqVTijjvuiOXl5SgWi/H+978/67KgYaVSKXp6euKHP/xh/PjHP44777yzI27X6qhWajhO/uu//iv+7M/+LHp6euJTn/pU1uXAoS0sLMTHP/7x+Ku/+qt45JFHsi4HGjI/Px8/+tGP4qtf/WrWpcCRvOpVr4qnn346br/99ojY+sDnrrvuiv/8z//UmUZX+e1vfxubm5sxPT0dr33ta+NDH/pQvOUtb4kXX3wxXv3qV2dWlxNjaIFqtRrvfve74xe/+EV8+9vf9n9YdJ3f/OY38fjjj0dExNjYWPzd3/1d/MM//EOUy+WMK4PGPPzww1EqleK2226Lm2++Ocrlcrzzne+Mr33ta1mXBg3J5XLboThi65aXiIiNjY2sSoJDyefzERExODgYERGnTp2KWq0Wa2trWZYlGEMrfOpTn4pf/OIX8d3vfnf7Lz10k8cffzze8Y53bD/O5XIREZnf/wONeuCBB+JnP/tZXLp0KS5duhT9/f3x0EMPxb333pt1adCQRx55JM6ePbv9+Fe/+lXceOONceutt2ZYFTTujjvuiFe96lXxxBNPRETEs88+G729vZmvH/MOB5rsypUr8fnPfz4uXrwYEVuDMl544YWoVqsZVwYHNz4+HpVKJR588MF4+umn43Of+1zcfffd0d/fn3Vp0JD6YM/6V09PTxQKhbjpppuyLg0a8uY3vzlWV1fjoYceipWVlbj//vvjve997/YHl9Atbrjhhrj33nvjk5/8ZFy+fDm+8IUvxNve9rY4cSLbu3wFY2iy73znO7G+vh5vectb4pZbbtn++tWvfpV1aXBgN998c3zzm9+ML3/5y3HnnXfGs88+6x5NgAzdeuut8fDDD8cDDzwQY2Njcfvtt8dnPvOZrMuCQ/nSl74UtVotXv/618ezzz7bEQM+c7VarZZ1EQAAAJAVJ8YAAAAkTTAGAAAgaYIxAAAASROMAQAASJpgDAAAQNIEYwAAAJImGAMAAJA0wRgAAICkCcYAAAAkTTAGAAAgaf8f5gYWMrgTU5sAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 1200x800 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sb\n",
    "from scipy.io import loadmat\n",
    "\n",
    "data = loadmat('data/ex7data1.mat')\n",
    "X = data['X']\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(12,8))\n",
    "ax.scatter(X[:, 0], X[:, 1])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "ad0bc612",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(matrix([[-0.792, -0.61 ],\n",
       "         [-0.61 ,  0.792]]),\n",
       " array([1.436, 0.564]),\n",
       " matrix([[-0.792, -0.61 ],\n",
       "         [-0.61 ,  0.792]]))"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def pca(X):\n",
    "    # normalize the features\n",
    "    X = (X - X.mean()) / X.std()\n",
    "    \n",
    "    # compute the covariance matrix\n",
    "    X = np.matrix(X)\n",
    "    cov = (X.T * X) / X.shape[0]\n",
    "    \n",
    "    # perform SVD\n",
    "    U, S, V = np.linalg.svd(cov)\n",
    "    \n",
    "    return U, S, V\n",
    "U, S, V = pca(X)\n",
    "U, S, V"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "81183539",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "matrix([[-4.747],\n",
       "        [-7.159],\n",
       "        [-4.796],\n",
       "        [-4.458],\n",
       "        [-4.803],\n",
       "        [-7.041],\n",
       "        [-4.97 ],\n",
       "        [-8.759],\n",
       "        [-6.223],\n",
       "        [-7.045],\n",
       "        [-6.917],\n",
       "        [-6.795],\n",
       "        [-6.344],\n",
       "        [-6.999],\n",
       "        [-4.546],\n",
       "        [-8.316],\n",
       "        [-7.169],\n",
       "        [-5.081],\n",
       "        [-8.541],\n",
       "        [-6.941],\n",
       "        [-8.598],\n",
       "        [-5.766],\n",
       "        [-8.202],\n",
       "        [-6.239],\n",
       "        [-4.379],\n",
       "        [-5.569],\n",
       "        [-7.539],\n",
       "        [-7.706],\n",
       "        [-5.172],\n",
       "        [-6.193],\n",
       "        [-6.244],\n",
       "        [-8.027],\n",
       "        [-4.812],\n",
       "        [-7.08 ],\n",
       "        [-5.46 ],\n",
       "        [-7.6  ],\n",
       "        [-4.396],\n",
       "        [-7.823],\n",
       "        [-3.405],\n",
       "        [-6.543],\n",
       "        [-7.179],\n",
       "        [-5.226],\n",
       "        [-4.831],\n",
       "        [-7.239],\n",
       "        [-4.362],\n",
       "        [-6.446],\n",
       "        [-2.691],\n",
       "        [-4.614],\n",
       "        [-5.882],\n",
       "        [-7.767]])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 现在我们有主成分（矩阵U），我们可以用这些来将原始数据投影到一个较低维的空间中。 对于这个任务，我们将实现一个计算投影并且仅选择顶部K个分量的函数，有效地减少了维数。\n",
    "def project_data(X, U, k):\n",
    "    U_reduced = U[:,:k]\n",
    "    return np.dot(X, U_reduced)\n",
    "\n",
    "Z = project_data(X, U, 1)\n",
    "Z"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "42cfe7c1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "matrix([[3.762, 2.896],\n",
       "        [5.673, 4.367],\n",
       "        [3.8  , 2.925],\n",
       "        [3.532, 2.719],\n",
       "        [3.806, 2.93 ],\n",
       "        [5.579, 4.295],\n",
       "        [3.939, 3.032],\n",
       "        [6.941, 5.343],\n",
       "        [4.931, 3.796],\n",
       "        [5.583, 4.297],\n",
       "        [5.481, 4.219],\n",
       "        [5.385, 4.145],\n",
       "        [5.027, 3.87 ],\n",
       "        [5.546, 4.269],\n",
       "        [3.602, 2.773],\n",
       "        [6.59 , 5.072],\n",
       "        [5.681, 4.373],\n",
       "        [4.026, 3.099],\n",
       "        [6.768, 5.21 ],\n",
       "        [5.5  , 4.234],\n",
       "        [6.813, 5.245],\n",
       "        [4.569, 3.517],\n",
       "        [6.499, 5.003],\n",
       "        [4.944, 3.806],\n",
       "        [3.47 , 2.671],\n",
       "        [4.413, 3.397],\n",
       "        [5.974, 4.598],\n",
       "        [6.107, 4.701],\n",
       "        [4.098, 3.155],\n",
       "        [4.907, 3.777],\n",
       "        [4.948, 3.809],\n",
       "        [6.361, 4.896],\n",
       "        [3.813, 2.935],\n",
       "        [5.61 , 4.319],\n",
       "        [4.326, 3.33 ],\n",
       "        [6.022, 4.636],\n",
       "        [3.484, 2.682],\n",
       "        [6.199, 4.772],\n",
       "        [2.698, 2.077],\n",
       "        [5.185, 3.991],\n",
       "        [5.689, 4.379],\n",
       "        [4.141, 3.188],\n",
       "        [3.828, 2.947],\n",
       "        [5.736, 4.416],\n",
       "        [3.456, 2.661],\n",
       "        [5.108, 3.932],\n",
       "        [2.133, 1.642],\n",
       "        [3.656, 2.814],\n",
       "        [4.661, 3.588],\n",
       "        [6.155, 4.738]])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 我们也可以通过反向转换步骤来恢复原始数据。\n",
    "def recover_data(Z, U, k):\n",
    "    U_reduced = U[:,:k]\n",
    "    return np.dot(Z, U_reduced.T)\n",
    "X_recovered = recover_data(Z, U, 1)\n",
    "X_recovered"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "f34bd32c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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PhldXV3xtre9LT7xiU/Ebbfddt57hoeHY3h4OK644opYv379BRULAAAAy0VZO9QjIyNx3333RX19fUREnD59OjZu3HjeewYGBiKdTsdtt90WGzdujOuvvz5effXVWdcPDw/H4ODglBcAAAAsN2UF6ksuuSTuueee2LhxY4yMjMSXv/zl+OhHP3reewYGBqJYLMZNN90U3d3dUVVVFffcc8+s6w8fPhyZTGbytWPHjnJKBAAAgCWRKpVKpXJv+tWvfhUf+chH4uc//3k89dRT592lHhkZiV/84heRy+UiIuLRRx+NQ4cORW9v74zrJ46ITxgcHIwdO3ZEoVCIzZs3l1sqAAAAlGVwcDAymcycObSsZ6gjIsbGxuLWW2+Nl156Kb7zne/MeeR73bp1k2E6ImLr1q3nPca9YcOG2LBhQ7llAQAAwJIqu8v3F77whfjpT38aTz75ZNTW1s65/siRI3HjjTdOXp84cSJ27txZ7tcCAADAslJWoO7t7Y0HH3ww2traImL8+eiBgYEYGxuLwcHBGBkZmXbPDTfcEE8//XQcO3YsXnzxxXjooYfi4x//+IIUDwAAAJVSVqB+4oknYnBwMK677rrYunXr5OvEiRNx9dVXx+OPPz7tnne9613x8MMPx5133hl79+6Nm2++Oe66664F+wsAAABAJSRqSraU5vswOAAAACyE+ebQsp+hBgAAAARqAAAASESgBgAAgAQEagAAAEhAoAYAAIAEBGoAAABIQKAGAACABARqAAAASECgBgAAgAQEagAAAEhAoAYAAIAEBGoAAABIQKAGAACABARqAAAASECgBgAAgAQEagAAAEhAoAYAAIAEBGoAAABIQKAGAACABARqAAAASECgBgAAgAQEagAAAEhAoAYAAIAEBGoAAABIQKAGAACABARqAAAASECgBgAAgAQEagAAAEhAoAYAAIAEBGoAAABIQKAGAACABARqAAAASECgBgAAgAQEagAAAEhAoAYAAIAEBGoAAABIQKAGAACABARqAAAASECgBgAAgAQEagAAAEhAoAYAAIAEBGoAAABIQKAGAACABARqAAAASECgBgAAgAQEagAAAEhAoAYAAIAEBGoAAABIQKAGAACABARqAAAASECgBgAAgAQEagAAAEjgokoXAAtpdKwUnT390TdUjLqadDTV10Z1VarSZQEAAKuQQM2q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Z8/GY489Fu95z3sqXRbMy8mTJ+NLX/pSHDlypNKlQNkGBgbi85//fGzcuDHe/e53x/PPP1/pkmBeent746WXXor/9t/+W2QymXjf+94Xv/7rvy5MsyJ9+9vfjt/+7d+udBmzWhP/q7rkkkvinnvuiY0bN8bIyEh8+ctfjo9+9KOVLgvKdvHFF8e3v/3t+PM///NKlwLzcujQobj99tvjqquuqnQpUJazZ89GsViMt7/97dHd3R0NDQ3xyU9+stJlwbzk8/moqqqKv/u7v4u///u/j6uuusrjYqxIzz33XJw6dSr27dtX6VJmtSaOfE/41a9+Fb/7u78bVVVV8YUvfKHS5UDZOjs743Of+1z8wR/8QRw7dqzS5cB5dXR0xA9/+MP46le/WulSoGzr1q2LkydPxmWXXRYR4//n0LXXXhu//OUvnXJj2fuHf/iHGB0djZaWlti5c2f8/u//flx33XVx9uzZWL9+faXLg3n71re+FXv27FnWj96siR3qiIixsbG49dZb46c//Wl8+9vf9h9DVozXX389nn322YiIaGxsjH//7/99PP7441EoFCpcGZzfo48+Gvl8Pi699NLYsmVLFAqF+MAHPhBf+9rXKl0azCmVSk2G6Yjxx28iIoaGhipVEsxbJpOJiIja2tqIiNi2bVuUSqXo7++vZFlQtm9961vxW7/1W5Uu47zWTKD+whe+ED/96U/jySefnPzHBVaCZ599Nt7//vdPXk+MDfAcFMvd/fffHy+++GI899xz8dxzz0VNTU088sgjccstt1S6NJjTsWPHYteuXZPXJ06ciIsvvjje8pa3VLAqmJ+3v/3tsW7duvjxj38cERGnTp2K6upqo99YUc6cORPPPPPMsn5+OmKNBOre3t548MEHo62tLSLGm4wMDAzE2NhYhSuDuTU1NUWxWIwjR47EyZMn44EHHoi9e/dGTU1NpUuD89q+fXvs3Llz8lVVVRXZbDY2bdpU6dJgTtdcc0309fXFI488Ej09PXH48OH42Mc+tqxnocKEjRs3xi233BJ//Md/HD/72c/ioYceit/6rd+Kiy5aU097ssJ1dHTEP/tn/yx+/dd/vdKlnNeaCNRPPPFEDA4OxnXXXRdbt26dfJ04caLSpcGctmzZEl//+tfjK1/5Slx11VVx6tQpz6QCLLK3vOUt8eijj8b9998fjY2Ncdlll8V9991X6bJg3v7iL/4iSqVS/Nqv/VqcOnVKQ1NWnJVw3DsiIlUqlUqVLgIAAABWmjWxQw0AAAALTaAGAACABARqAAAASECgBgAAgAQEagAAAEhAoAYAAIAEBGoAAABIQKAGAACABARqAAAASECgBgAAgAQEagAAAEjg/wcLt4qy0ECgFAAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 1200x800 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(figsize=(12,8))\n",
    "ax.scatter(list(X_recovered[:, 0]), list(X_recovered[:, 1]))\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.5"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
